import timePlugIn from "../../ipha_tool/TimePlugIn";
import Frame from "../frameNamespace";
import BundleManager from "../managers/bundleManager";
import GameManager from "../managers/gameManager";
import SoundManager from "../managers/soundManager";
import LocalStorageService from "../services/localStorageService";
import PlatformService from "../services/platformService";
import RecordDataService from "../services/recordDataService";
import UIService from "../services/uiService";
import UserService from "../services/userService";
import SystemBase from "./systemBase";

class OverallSystem extends SystemBase {
    protected _systemName: string = "主系统";

    constructor() {
        super();
    }

    private _managers: Frame.Managers = <Frame.Managers>{};
    private _servers: Frame.Services = <Frame.Services>{};

    Initialize(): void {
        super.Initialize();

        console.group("初始化");

        console.group("初始化服务");
        this._servers = {
            localStorageSrv: new LocalStorageService(),
            platformSrv: new PlatformService(),
            userSrv: new UserService(),
            uiSrv: new UIService(),
            recordDataSrv: new RecordDataService(),
        }
        console.groupEnd(); //初始化服务
        console.log("-----服务--初始化完毕-----");

        console.group("初始化管理类");
        this._managers = {
            gameMgr: new GameManager(),
            soundMgr: new SoundManager(),
            bundleMgr: undefined,
        }
        console.groupEnd(); //初始化管理类

        console.log("-----管理--初始化完毕-----");

        console.groupEnd(); //初始化


        timePlugIn();
        this._servers.userSrv._initPower();
        this._servers.userSrv._initCoin();
    }

    /**
     * 获取场景主节点
     */
    Canvas() {
        return cc.find("Canvas");
    }

    /**
     * 获取场景主节点的某一组件
     */
    Component() {
        return this.Canvas().getComponent(cc.Component);
    }

    /**
     * 初始化 bundle 管理
     */
    InitBundle() {
        this._managers.bundleMgr = new BundleManager();
    }

    /**
    通过事件名发送自定义事件 目标节点Canvas
    @param type 事件名
    @param arg1 参数1
    @param arg2 参数2
    @param arg3 参数3
    @param arg4 参数4
    @param arg5 参数5
    
    @example 
    ```js
    eventTarget.emit('fire', event);
    eventTarget.emit('fire', message, emitter);
    ``` 
    */
    emit(type: string, arg1?: any, arg2?: any, arg3?: any, arg4?: any, arg5?: any) {
        this.Canvas().emit(type, arg1, arg2, arg3, arg4, arg5);
    }

    /**
    在节点 Canvas 上注册指定类型的回调函数
    @param type 事件名
    @param callback 回调函数
    @param target 回调函数this目标
    @param useCapture 当设置为true时，侦听器将在捕获阶段(在最终目标发出之前)触发，否则将在冒泡阶段触发。
    */
    on<T extends Function>(type: string, callback: T, target?: any, useCapture?: boolean) {
        this.Canvas().on(type, callback, target, useCapture);
    }

    /**
    在节点 Canvas 上注册单次指定类型的回调函数
    @param type 事件名
    @param callback 回调函数
    @param target 回调函数this目标
    @param useCapture 当设置为true时，侦听器将在捕获阶段(在最终目标发出之前)触发，否则将在冒泡阶段触发。
    */
    once<T extends Function>(type: string, callback: T, target?: any, useCapture?: boolean) {
        this.Canvas().once(type, callback, target, useCapture);
    }

    /**
    在节点 Canvas 上删除之前与同类型，回调，目标或 useCapture 注册的回调。
    @param type 事件名
    @param callback 回调函数
    @param target 回调函数this目标
    @param useCapture 当设置为true时，侦听器将在捕获阶段(在最终目标发出之前)触发，否则将在冒泡阶段触发。
    */
    off<T extends Function>(type: string, callback: T, target?: any, useCapture?: boolean) {
        this.Canvas().off(type, callback, target, useCapture);
    }

    loadScene(name: string) {
        console.log("正在加载场景:", name);
        return new Promise<void>((resolve) => {
            cc.director.loadScene(name, resolve);
        });
    }

    get Managers() { return this._managers; }
    get Servers() { return this._servers; }
}

export function mgrs() {
    return UMe.Managers;
}

export function sers() {
    return UMe.Servers;
}

function IphaOSInit(): OverallSystem {
    try {
        window["iphaOS"] = new OverallSystem();
        return window["iphaOS"];
    } catch (err) {
        console.error("主系统创建失败 :", err);
        return null;
    }
}

let UMe: OverallSystem = IphaOSInit();

export default UMe;